<template>
<div class="CalendarMonth">
<table>
  <thead>
    <tr>
      <th>一</th>
      <th>二</th>
      <th>三</th>
      <th>四</th>
      <th>五</th>
      <th style="color: red;">六</th>
      <th style="color: red;">日</th>
    </tr>
  </thead>
  <tbody>
    <tr v-for="(week, weekIndex) in dayArr" :key="weekIndex">
      <td 
        v-for="(day, dayIndex) in week" 
        :key="dayIndex"
        :class="{ 
          today: day.isToday, 
          selected: selectedDate === day, 
          red: day.weekDay === 5 || day.weekDay === 6
        }"
        @click="selectDate(day)"
      >
        <span :style="{opacity: day.thisMonth ? 1 : 0.4}">{{ day.day }}</span>
      </td>
    </tr>
  </tbody>
</table>
</div>
</template>

<script setup>
const props = defineProps({
  year: {
    type: Number,
    required: true
  },
  month: {
    type: Number,
    required: true
  }
})


const year = props.year;
const month = props.month;
// 生成当月日历的二维数组
function getMonthCalendarGrid(year, month) {
   // JS月份1-12，Date对象月份0-11
   // 获取上月天数
  const prevMonth = month === 1 ? 12 : month -1
  const pervMonthYear = month === 1 ? year - 1 : year
  const daysInPreMonth = new Date(pervMonthYear, prevMonth, 0).getDate()
  // 本月天数
  const daysInMonth = new Date(year, month, 0).getDate()
  // 第一天周几（0=周日）
  const firstDayWeek = new Date(year, month - 1, 1).getDay();


  // 补满前置空格: 上个月倒数prefix天
  let prefix = firstDayWeek === 0 ? 6 : firstDayWeek - 1
  const cells = [];
  for (let i = daysInPreMonth - prefix + 1, week = 0; i <= daysInPreMonth; i++) {
    cells.push({
      day: i, 
      thisMonth: false, 
      isToday: false,
      weekDay: week % 7 // 记下星期几 (0为周一)
    })
  }


  // 填入天号
  for (let d = 1, week = cells.length; d <= daysInMonth; d++, week++) {
    // 判断是不是当天
    const isToday = (d === new Date().getDate() && month === new Date().getMonth() + 1 && year === new Date().getFullYear())
    cells.push({
      day: d, 
      thisMonth: true, 
      isToday,
      weekDay: week % 7
    })
  }


  // 补足结尾空格: 下月天号
  let suffix = 42 - cells.length;
  for (let i = 1, week = cells.length; i <= suffix; i++, week++) {
    cells.push({
      day: i,
      thisMonth: false,
      isToday: false,
      weekDay: week % 7
    })
  }


  // 切割为一周一行的二维数组
  const weeks = [];
  for (let i = 0; i < cells.length; i += 7) {
    weeks.push(cells.slice(i, i+7))
  }
  return weeks;
}


import {ref, watch} from 'vue'
const dayArr = ref([])
// 随时更新为所选年月的日历数据
watch(() => [props.year, props.month], ([newYear, newMonth]) => {
  dayArr.value = getMonthCalendarGrid(newYear, newMonth)
}, { immediate: true })


// 点击处理函数
const selectedDate = ref(null)
const emit = defineEmits(['selectedDay'])
function selectDate(day) {
  if (day.thisMonth) {
    // 检查是否点击了已选中的日期
    if (selectedDate.value && selectedDate.value.day === day.day && selectedDate.value.thisMonth) {
      // 如果点击了已选中的日期，则清除选中状态
      selectedDate.value = null;
    } else {
      // 如果点击了未选中的日期，则设置为选中状态
      selectedDate.value = day;
      emit('selectedDay', day.day);
    }
  }
}

</script>

<style scoped>
.CalendarMonth {
  width: 100%;
}

table {
  width: 100%;
  border-collapse: separate;
  border-spacing: 0;
  background: #e0e5ec;
  border-radius: 16px;
  overflow: hidden;
  box-shadow: 
    5px 5px 10px #b8bdc5, 
    -5px -5px 10px #ffffff;
}

table th {
  padding: 12px 0;
  text-align: center;
  background: #d1d9e6;
  color: #4d535f;
  font-weight: 600;
  border-bottom: 1px solid #b8bdc5;
}

table td {
  /* padding: 12px 0; */
  text-align: center;
  border: 1px solid transparent;
  color: #4d535f;
  font-weight: 500;
  transition: all 0.2s ease;
  cursor: pointer;
}

table td span {
  display: block;
  width: 50px;
  aspect-ratio: 1 / 1;
  line-height: 50px;
  margin: 0 auto;
  transition: all 0.2s ease;
}

table td:hover span {
  background: #d1d9e6;
  box-shadow: 
    2px 2px 4px #b8bdc5, 
    -2px -2px 4px #ffffff;
}

table td.today span {
  background: #3a404d;
  color: white;
  box-shadow: 
    inset 2px 2px 4px #2c313d, 
    inset -2px -2px 4px #484f5d;
}

table td.selected span {
  background: #6c8beb;
  color: white;
  box-shadow: 
    inset 2px 2px 4px #4a69d9, 
    inset -2px -2px 4px #8eacff;
}

table td.red {
  color: #ff6b6b;
}

table td.red span {
  color: #ff6b6b;
}

table td.today.red span {
  color: white;
}
</style>